package com.nico.chatvoiceview

import android.annotation.SuppressLint
import android.app.Activity
import android.app.Dialog
import android.content.Context
import android.content.res.Resources
import android.graphics.Color
import android.graphics.Rect
import android.graphics.drawable.ColorDrawable
import android.support.constraint.ConstraintLayout
import android.util.DisplayMetrics
import android.util.Log
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.View.FOCUSABLE
import android.view.View.NOT_FOCUSABLE
import android.view.ViewTreeObserver
import android.view.WindowManager
import android.widget.EditText
import android.widget.TextView
import com.nico.voiceview.MainActivity
import com.nico.voiceview.R


class ChatVoiceDialog:Dialog {
    sealed interface Status {
        object INIT:Status
        // 取消
        object LEFT:Status
        // 识别
        object CENTER:Status
        // 发送转写中
        object RIGHT:Status
        //发送转写松手
        object RESULT:Status
    }
    private var mStatus: Status= Status.INIT
    private var mVoiceViewCallback: VoiceViewCallback?=null
    private lateinit var mBottomVolumRect:View
    private lateinit var mLanguageSwitch:View
    private lateinit var mEditResultTips:View
    private lateinit var mBottomTips:TextView
    private lateinit var mCancel:ChatItemView
    private lateinit var mSendOriginalVoice:ChatItemView
    private lateinit var mRecognizeEdittext:EditText
    private lateinit var mRecognizeLayout:View
    private lateinit var mRecordingLayout:View
    private lateinit var mTimeTips:TextView
    private lateinit var mTextTips:TextView
    private lateinit var mSend:ChatItemView
    private var mScreenWidth: Int = 0
    private var mScreenHeight: Int = 0
    private var mStatusBarHeight: Int = 0
    private var mIsKeyboardShowing=false

    private lateinit var mCancelOriginalLayoutParams:ConstraintLayout.LayoutParams
    private lateinit var mRecognizeLayoutOriginalLayoutParams:ConstraintLayout.LayoutParams
    /**
     * 屏幕的中点坐标
     */
    private var mWindowCenterX = 0

    private var mActivity:Activity?=null
    constructor(context: Context) : this(context,0) {
        mActivity=context as Activity
    }
    constructor(context: Context, themeResId:Int) : super (context,themeResId) {
        initView(context)
    }

    @SuppressLint("ClickableViewAccessibility")
    private fun initView(context: Context) {
        val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        val display = windowManager.defaultDisplay
        val realDisplayMetrics = DisplayMetrics()
        // 使用 getRealMetrics() 获取包含虚拟导航栏的屏幕尺寸
        display.getRealMetrics(realDisplayMetrics)
        val widthPixels = realDisplayMetrics.widthPixels
        mWindowCenterX = widthPixels / 2
        val inflate =
            LayoutInflater.from(context).inflate(R.layout.dialog_chat_voice_layout, null, false)
        setContentView(inflate)

        setOnDismissListener {
            resetStatus()
        }

        val resources: Resources = context.resources
        val resourceId: Int = resources.getIdentifier("status_bar_height", "dimen", "android")
        mStatusBarHeight = resources.getDimensionPixelSize(resourceId)

        // 使用 getRealMetrics() 获取包含虚拟导航栏的屏幕尺寸
        display.getRealMetrics(realDisplayMetrics)

        mScreenWidth = realDisplayMetrics.widthPixels
        mScreenHeight = realDisplayMetrics.heightPixels


        mCancel = findViewById<ChatItemView>(R.id.cancel)
        mSend = findViewById<ChatItemView>(R.id.send)
        mSendOriginalVoice = findViewById<ChatItemView>(R.id.send_original_voice)
        mBottomTips = findViewById<TextView>(R.id.bottom_tips)
        mCancel.setType(ChatItemView.Type.CANCEL)
        mCancel.setText("取消")
        mSend.setType(ChatItemView.Type.SEND)
        mSend.setText("发送文字")
        mSendOriginalVoice.setType(ChatItemView.Type.ORIGINAL)
        mSendOriginalVoice.setChecked(true)
        mSendOriginalVoice.setText("发送原语音")

        mBottomVolumRect = findViewById<View>(R.id.bottom_volume_rect)
        mRecognizeEdittext = findViewById<EditText>(R.id.recognize_edittext)
        mRecognizeLayout = findViewById<View>(R.id.recognize_layout)
        mRecordingLayout = findViewById<View>(R.id.recording_layout)
        mTimeTips = findViewById<TextView>(R.id.time_tips)
        mTextTips = findViewById<TextView>(R.id.text_tips)
        mLanguageSwitch = findViewById<TextView>(R.id.language_switch)
        mEditResultTips = findViewById<TextView>(R.id.edit_result_tips)
        mCancelOriginalLayoutParams= mCancel.layoutParams as ConstraintLayout.LayoutParams
        mRecognizeLayoutOriginalLayoutParams= mRecognizeLayout.layoutParams as ConstraintLayout.LayoutParams

        mCancel.setOnClickListener { dismiss() }
        mSend.setOnClickListener {
            //mVoiceViewCallback?.textAction()
        }

        mLanguageSwitch.setOnClickListener {
            mVoiceViewCallback?.languageAction()
        }
        mSendOriginalVoice.setOnClickListener {
            mVoiceViewCallback?.speechAction()
            dismiss()
        }


        window!!.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        val params: WindowManager.LayoutParams = window!!.attributes
        params.width = WindowManager.LayoutParams.MATCH_PARENT
        params.height = WindowManager.LayoutParams.MATCH_PARENT
        window!!.setAttributes(params)
    }

    fun responseTouchEvent(event: MotionEvent){
        val action = event.action
        when (action) {
            MotionEvent.ACTION_DOWN -> {
                mStatus = Status.INIT
                mVoiceViewCallback?.startRecord()
            }
            MotionEvent.ACTION_MOVE -> doMoveAction(event)
            MotionEvent.ACTION_UP -> doUpAction(event)
        }
    }


    private fun doUpAction(event: MotionEvent?) {
        mVoiceViewCallback?.stopRecord()
        when (mStatus) {
            Status.LEFT, Status.INIT -> {
                mVoiceViewCallback?.cancelAction()
                dismiss()
                return
            }
            Status.CENTER -> {
                mVoiceViewCallback?.speechAction()
                dismiss()
                return
            }
            Status.RIGHT -> {
                mStatus = Status.RESULT
                //显示中间的发送原语音
                mSend.setType(ChatItemView.Type.RESULT)
                mCancel.setChecked(true)
                mSendOriginalVoice.visibility=View.VISIBLE
                mSendOriginalVoice.setChecked(true)
                mBottomVolumRect.visibility=View.INVISIBLE
                mLanguageSwitch.visibility=View.VISIBLE
                mEditResultTips.visibility=View.VISIBLE
            }
            else -> {}
        }
    }




    private fun doMoveAction(event: MotionEvent) {
        val height = mBottomVolumRect.height
        if(event.rawY< mScreenHeight-height){
            if(event.rawX>mScreenWidth/2){
                // right
                mStatus = Status.RIGHT
                //showBottomTips("松开发送")
            }else{
                //left
                mStatus = Status.LEFT
               // showBottomTips("取消发送")
            }
        }else{
            //center
            mStatus = Status.CENTER
           // showBottomTips("松开发送")
        }
        updateStatusView()
    }

    fun setViewCallback(callback: MainActivity) {
        mVoiceViewCallback = callback
    }


    private fun showBottomTips(tips:String){
        mBottomTips.text = tips
        mTextTips.text=tips
    }


    /**
     * 语音文本
     * */
    public fun showRecognizeContent(content:String){
        mRecognizeEdittext.setText(content)
        mRecognizeEdittext.setSelection(content.length)
    }

    public fun showRecordingTime(time:String){
        mTimeTips.text=time
    }

    private fun showRecordingTips(tips:String){
        mTextTips.text=tips
    }




    private fun updateStatusView(){
        when(mStatus){
            Status.RIGHT->{
                mCancel.setChecked(false)
                mSend.setChecked(true)
                mRecordingLayout.visibility=View.GONE
                mRecognizeLayout.visibility=View.VISIBLE
                showBottomTips("松开发送")
            }
            Status.LEFT->{
                mCancel.setChecked(true)
                mSend.setChecked(false)
                mRecordingLayout.visibility=View.VISIBLE
                mRecognizeLayout.visibility=View.GONE
                mRecordingLayout.setBackgroundResource(R.drawable.shape_left_rx_10dp)
                showBottomTips("取消发送")
            }
            Status.CENTER->{
                mCancel.setChecked(false)
                mSend.setChecked(false)
                mRecordingLayout.visibility=View.VISIBLE
                mRecognizeLayout.visibility=View.GONE
                mRecordingLayout.setBackgroundResource(R.drawable.shape_center_rx_10dp)
                showBottomTips("松开发送")
            }
            else->{
                mCancel.setChecked(false)
                mSend.setChecked(false)
            }
        }
    }


   private var activityRootViewGlobalLayoutListener: ViewTreeObserver.OnGlobalLayoutListener = ViewTreeObserver.OnGlobalLayoutListener {
       val rootView = mActivity?.window?.decorView?.rootView
       val rect = Rect()
       rootView?.getWindowVisibleDisplayFrame(rect)

       val screenHeight = rootView?.height?:0
       val keypadHeight = mScreenHeight - rect.bottom

       // 键盘高度超过屏幕高度的15%则认为键盘显示
       val keyboardThreshold = screenHeight * 0.15

       if (keypadHeight > keyboardThreshold) {
           if (!mIsKeyboardShowing) {
               mIsKeyboardShowing = true
           }
       } else {
           if (mIsKeyboardShowing) {
               mIsKeyboardShowing = false
           }
       }
       adjustLayoutForKeyboard(mIsKeyboardShowing, keypadHeight)
   }

    private fun setupKeyboardListener() {

        val rootView = mActivity?.window?.decorView?.rootView
        rootView?.viewTreeObserver?.addOnGlobalLayoutListener(activityRootViewGlobalLayoutListener)
    }

    private fun adjustLayoutForKeyboard(isShowing: Boolean, keyboardHeight: Int) {
        val width = TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP,
            60f,
            context.resources.displayMetrics
        )
        val cancelLayoutParams =ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.WRAP_CONTENT,ConstraintLayout.LayoutParams.WRAP_CONTENT)
        val recognizeLayoutParams = ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.WRAP_CONTENT,ConstraintLayout.LayoutParams.WRAP_CONTENT)
        Log.d(javaClass.simpleName, "adjustLayoutForKeyboard1 ======isShowing:${isShowing}  keyboardHeight:${keyboardHeight}  ${mRecognizeLayout.height}  ${mRecognizeLayout.top} ${mRecognizeLayout.bottom}  ${mEditResultTips.height}  ${mLanguageSwitch.height}")
        if (isShowing) {
           //deep copy
            cancelLayoutParams.width=mCancelOriginalLayoutParams.width
            cancelLayoutParams.height=mCancelOriginalLayoutParams.height
            cancelLayoutParams.horizontalChainStyle=mCancelOriginalLayoutParams.horizontalChainStyle
            cancelLayoutParams.bottomToTop=mCancelOriginalLayoutParams.bottomToTop
            cancelLayoutParams.startToStart=mCancelOriginalLayoutParams.startToStart
            cancelLayoutParams.endToStart=mCancelOriginalLayoutParams.endToStart
            cancelLayoutParams.marginStart=mCancelOriginalLayoutParams.marginStart


            recognizeLayoutParams.bottomMargin=20
            recognizeLayoutParams.height=mRecognizeLayout.height-mRecognizeLayout.top-mEditResultTips.height-mLanguageSwitch.height-100
          //  recognizeLayoutParams.height=100
            recognizeLayoutParams.width=mRecognizeLayoutOriginalLayoutParams.width
            recognizeLayoutParams.bottomToTop=mRecognizeLayoutOriginalLayoutParams.bottomToTop
            recognizeLayoutParams.marginStart=mRecognizeLayoutOriginalLayoutParams.marginStart
            recognizeLayoutParams.marginEnd=mRecognizeLayoutOriginalLayoutParams.marginEnd
            mCancel.layoutParams=cancelLayoutParams
            mRecognizeLayout.layoutParams=recognizeLayoutParams
        } else {
            resetViewsLayoutParams()
        }

     //   Log.d(javaClass.simpleName, "adjustLayoutForKeyboard2 ======isShowing:${isShowing}  keyboardHeight:${keyboardHeight} ${cancelLayoutParams.bottomMargin}")
    }


    private fun resetStatus(){
        resetViewsLayoutParams()
        mCancel.setChecked(false)
        mCancel.setType(ChatItemView.Type.CANCEL)
        mSend.setChecked(false)
        mSend.setType(ChatItemView.Type.SEND)
        mBottomVolumRect.visibility=View.VISIBLE
        mSendOriginalVoice.visibility=View.GONE
        mLanguageSwitch.visibility=View.GONE
        mEditResultTips.visibility=View.GONE
        val rootView = mActivity?.window?.decorView?.rootView
       // rootView?.viewTreeObserver?.addOnGlobalLayoutListener
        //rootView?.viewTreeObserver?.addOnGlobalLayoutListener(activityRootViewGlobalLayoutListener)
        rootView?.viewTreeObserver?.removeOnGlobalLayoutListener(activityRootViewGlobalLayoutListener)
    }

    private fun resetViewsLayoutParams(){
        mCancel.layoutParams=mCancelOriginalLayoutParams
        mRecognizeLayout.layoutParams=mRecognizeLayoutOriginalLayoutParams
    }
    override fun show() {
        super.show()
        // 设置键盘监听
        setupKeyboardListener()
    }
}